﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using GeoCoding.Services;
using GeoCoding;
using GeoCoding.Services.Google;
using System.IO;

namespace MKGeocoder
{
    public partial class MainForm : Form
    {
        private string _inputFileName;
        private string _outputFileName;
        private string _outputExFileName;        
        private string _apiKey;

        public MainForm()
        {
            InitializeComponent();           
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {            
            IGeoCoder geoCoder = new GoogleGeoCoder(_apiKey);


            StreamWriter w = new StreamWriter(_outputFileName, true);
            StreamWriter wex = new StreamWriter(_outputExFileName, false);
            using (StreamReader r = new StreamReader(_inputFileName))
            {
                string[] sep = new string[] { "\r\n" };
                String[] lines = r.ReadToEnd().Split(sep, StringSplitOptions.RemoveEmptyEntries);
                int total = lines.Length;
                int count = 0;
                foreach(string line in lines)
                {
                    DataGridViewRow row = new DataGridViewRow();
                    DataGridViewTextBoxCell cell = new DataGridViewTextBoxCell();
                    cell.Value = line;
                    row.Cells.Insert(0, cell);
                    String outputString = string.Empty;
                    Address[] addresses = null;
                    try
                    {
                        addresses = geoCoder.GeoCode(line);
                    }
                    catch(System.Net.WebException)
                    {
                        outputString = String.Format("{0}\t\tGoogle Exception: ", line);
                        DataGridViewTextBoxCell cellError = new DataGridViewTextBoxCell();
                        cellError.Value = "Google Exception";
                        row.Cells.Insert(1, cellError);

                        wex.WriteLine(outputString);
                        backgroundWorker1.ReportProgress((int)((double)++count * 100 / (double)total), row);                    

                        continue;
                    }
                   
                    if (addresses.Length != 0)
                    {
                        outputString = String.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}", line, addresses[0].Street,
                            addresses[0].Country, addresses[0].PostalCode, addresses[0].Coordinates.Latitude, addresses[0].Coordinates.Longitude);
                        DataGridViewTextBoxCell cellLat = new DataGridViewTextBoxCell();
                        cellLat.Value = addresses[0].Coordinates.Latitude.ToString();

                        DataGridViewTextBoxCell cellLong = new DataGridViewTextBoxCell();
                        cellLong.Value = addresses[0].Coordinates.Longitude.ToString();

                        row.Cells.Insert(1, cellLat);
                        row.Cells.Insert(2, cellLong);
                        w.WriteLine(outputString);
                    }
                    else if (addresses.Length == 0)
                    {
                        outputString = String.Format("{0}\t\tCannot Parse", line);
                        DataGridViewTextBoxCell cellError = new DataGridViewTextBoxCell();
                        cellError.Value = "Cannot Parse";
                        row.Cells.Insert(1, cellError);
                        wex.WriteLine(outputString);
                    }
                    else if (addresses.Length > 1)
                    {
                        outputString = String.Format("{0}\t\tMultiple Addresses found", line);
                        DataGridViewTextBoxCell cellError = new DataGridViewTextBoxCell();
                        cellError.Value = "Multiple Address Found" + addresses.Length.ToString();
                        row.Cells.Insert(1, cellError);
                        wex.WriteLine(outputString);
                    }
                    
                    backgroundWorker1.ReportProgress((int)((double)++count * 100 / (double)total), row);                    
                }
            }

            w.Close();
            wex.Close();
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
            if (progressBar1.Value >= 100.0)
            {
                 progressBar1.Visible = false;                
            }
            dataGridViewOutput.Rows.Add((e.UserState as DataGridViewRow));
        }      

        private void buttonStart_Click(object sender, EventArgs e)
        {            
            _apiKey = textBoxAPIKey.Text;
            
            if (String.IsNullOrEmpty(_apiKey))
            {
                MessageBox.Show("API Key missing, Get it from Google");
                return;
            }

            progressBar1.Visible = true;
            backgroundWorker1.RunWorkerAsync();
        }

        private void buttonIPChooser_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                _inputFileName = openFileDialog1.FileName;
                _outputFileName = _inputFileName + ".mkgeocoded.txt";
                _outputExFileName = _inputFileName + ".mkgeocoded_exceptions.txt";
                textBoxIPFile.Text = _inputFileName;
            }
        }      
    }
}
